package com.sky.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.UUID;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.sky.context.ThreadLocalUtil;
import com.sky.dto.*;
import com.sky.entity.AddressBook;
import com.sky.entity.OrderDetail;
import com.sky.entity.Orders;
import com.sky.entity.ShoppingCart;
import com.sky.exception.BusinessException;
import com.sky.mapper.AddressMapper;
import com.sky.mapper.OrderDetailMapper;
import com.sky.mapper.OrderMapper;
import com.sky.mapper.ShoppingCartMapper;
import com.sky.result.PageResult;
import com.sky.result.Result;
import com.sky.service.OrderService;
import com.sky.vo.OrderPaymentVO;
import com.sky.vo.OrderStatisticsVO;
import com.sky.vo.OrderSubmitVO;
import com.sky.vo.OrderVO;
import com.sky.websocket.WebSocketServer;
import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PutMapping;

import javax.xml.crypto.Data;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class OrderServiceImpl implements OrderService {
    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private AddressMapper addressMapper;

    @Autowired
    private ShoppingCartMapper shoppingCartMapper;

    @Autowired
    private WebSocketServer webSocketServer;

    @Autowired
    private OrderDetailMapper orderDetailMapper;

    @Override
    public OrderSubmitVO OrderSubmit(OrdersSubmitDTO dto) {
      /*  AddressBook addressBook = addressMapper.findById(dto.getAddressBookId());
        if(addressBook==null){
            throw new BusinessException("请填写收货地址");
        }


        Orders orders = BeanUtil.copyProperties(dto, Orders.class);
        String uuid = IdUtil.fastSimpleUUID();
        orders.setNumber(uuid);
        orders.setStatus(Orders.PENDING_PAYMENT);
        orders.setUserId(ThreadLocalUtil.getCurrentId());
        orders.setOrderTime(LocalDateTime.now());
        orders.setPayStatus(Orders.UN_PAID);

        orders.setPhone(addressBook.getPhone());
        orders.setAddress(addressBook.getProvinceName()+addressBook.getCityName()+addressBook.getDistrictName());
        orders.setConsignee(addressBook.getConsignee());
        orderMapper.save(orders);
        List<ShoppingCart> shoppingCartList = shoppingCartMapper.findByUserId(orders.getUserId());
        List<OrderDetail> list =new ArrayList<>();
        if(CollectionUtil.isNotEmpty(shoppingCartList)){
            for (ShoppingCart shoppingCart : shoppingCartList) {
                OrderDetail orderDetail = BeanUtil.copyProperties(shoppingCart, OrderDetail.class);
                orderDetail.setOrderId(orders.getId());
                list.add(orderDetail);
            }
            orderDetailMapper.batchSave(list);
        }
        shoppingCartMapper.deleteByUserId(orders.getUserId());
        return  OrderSubmitVO.builder()
                .id(orders.getId())
                .orderAmount(orders.getAmount())
                .orderNumber(orders.getNumber())
                .orderTime(orders.getOrderTime())
                .build();*/
        AddressBook addressBook = addressMapper.findById(dto.getAddressBookId());
        if(addressBook==null){
            throw new BusinessException("请选择送货地址");
        }
        Orders orders = BeanUtil.copyProperties(dto, Orders.class);
        String uuid = IdUtil.fastSimpleUUID();
        orders.setNumber(uuid);
        orders.setUserId(ThreadLocalUtil.getCurrentId());
        orders.setStatus(Orders.PENDING_PAYMENT);
        orders.setOrderTime(LocalDateTime.now());
        orders.setPayStatus(Orders.UN_PAID);
        orders.setPhone(addressBook.getPhone());
        orders.setAddress(addressBook.getProvinceName()+addressBook.getCityName()+addressBook.getDistrictName());
        orders.setConsignee(addressBook.getConsignee());
        orderMapper.save(orders);
        List<ShoppingCart> list = shoppingCartMapper.findByUserId(orders.getUserId());
        List<OrderDetail> orderDetails =new ArrayList<>();
        if(CollectionUtil.isNotEmpty(list)){
            for (ShoppingCart shoppingCart : list) {
                OrderDetail orderDetail = BeanUtil.copyProperties(shoppingCart, OrderDetail.class);
                orderDetail.setOrderId(orders.getId());
                orderDetails.add(orderDetail);
            }
            orderDetailMapper.batchSave(orderDetails);
        }
        shoppingCartMapper.deleteByUserId(orders.getUserId());
         return OrderSubmitVO.builder()
                     .id(orders.getId())
                     .orderAmount(orders.getAmount())
                     .orderNumber(orders.getNumber())
                     .orderTime(orders.getOrderTime())
                     .build();
        }

    // 订单支付
    public OrderPaymentVO payment(OrdersPaymentDTO ordersPaymentDTO) throws Exception {

        // 1.直接修改订单状态
        Orders ordersDB = orderMapper.getByNumber(ordersPaymentDTO.getOrderNumber());

        // 根据订单id更新订单的状态、支付方式、支付状态、结账时间
        Orders orders = Orders.builder()
                .id(ordersDB.getId())
                .status(Orders.TO_BE_CONFIRMED)
                .payStatus(Orders.PAID)
                .checkoutTime(LocalDateTime.now())
                .build();

        orderMapper.update(orders);

        Map<String,Object> map =new HashMap<>();
        map.put("type",1);
        map.put("orderId",orders.getId());
        map.put("content","订单号:"+ordersPaymentDTO.getOrderNumber());
        webSocketServer.sendToAllClient(JSON.toJSONString(map));



        // 2. 返回一个空结果
        OrderPaymentVO vo = OrderPaymentVO.builder()
                .nonceStr("52640818796650160489223277005653")
                .paySign("iHYG8l90s5nIXMWgkmN6PX2+3e4mW4spWMOLnvdQZTePZiMy/CDiP3CfvsByp65PpnVcmG1Br1EY7f46xeToKOlmK2qe00IFBaXUtNH/6+k5Ij7fXRKNRQxQuODegkWSvX+fw2FKo8qKT1clJd5/T/Hkwu6cSDZGqHIaW3eqha14HRpsT5siHlwoHw04X5wVvnktAx4Koko/tsMtI/t/dkCDvIbCve1ut7/FVVtlgNJKMR6rzY0wiyroseSy3qjbw6BUL+HPnxlLqF2PNbk9jkimyxJrwzxk2NFxjHM87tybMBMTITCuIuH9hZCFFbJTFsG9BYsL2H7GcsaYmzIoig==")
                .timeStamp("1683009626")
                .signType("RSA")
                .packageStr("prepay_id=wx02144025953621ab23eaa2fc334f2a0000")
                .build();

        return vo;
    }

    @Override
    public PageResult historyOrders(OrdersPageQueryDTO dto) {
        dto.setUserId(ThreadLocalUtil.getCurrentId());
        int page = dto.getPage();
        int pageSize = dto.getPageSize();
        if(page==0){
            page=1;
        }
        if(pageSize==0){
            pageSize=10;
        }
        PageHelper.startPage(page,pageSize);
        List<Orders> ordersList = orderMapper.findList(dto);
        PageInfo<Orders> pageInfo = PageInfo.of(ordersList);
        long total = pageInfo.getTotal();
        List<OrderVO> voList = new ArrayList<>();
        if(CollectionUtil.isNotEmpty(ordersList)){
                voList = ordersList.stream().map(order -> {
                List<OrderDetail> orderDetailList = orderDetailMapper.findByOrderId(order.getId());
                OrderVO vo = BeanUtil.copyProperties(order, OrderVO.class);
                vo.setOrderDetailList(orderDetailList);
                return vo;
            }).collect(Collectors.toList());

        }
        return new PageResult(total,voList);


    }

    @Override
    public OrderVO findById(Long id) {
       Orders order = orderMapper.findById(id);
        List<OrderDetail> detailList = orderDetailMapper.findByOrderId(id);
        OrderVO vo = BeanUtil.copyProperties(order, OrderVO.class);
        vo.setOrderDetailList(detailList);
        return vo;
    }

    @Override
    public void orderCancel(Long id) {
        Orders order = orderMapper.findById(id);
        Integer status = order.getStatus();
        if(status>2){
            throw new BusinessException("请联系商家进行退款");
        }else {
            order.setStatus(Orders.CANCELLED);
            order.setCancelTime(LocalDateTime.now());
            order.setCancelReason("用户取消");
            if(order.getPayStatus().equals(Orders.PAID)){
                order.setPayStatus(Orders.REFUND);
            }
        }
        orderMapper.update(order);
    }

    @Override
    public void repetition(Long id) {
        List<OrderDetail> orderDetailList = orderDetailMapper.findByOrderId(id);
        if(CollectionUtil.isNotEmpty(orderDetailList))
        {
            List<ShoppingCart> shoppingCartList = orderDetailList.stream().map(orderDetail -> {
                ShoppingCart shoppingCart = BeanUtil.copyProperties(orderDetail, ShoppingCart.class);
                shoppingCart.setUserId(ThreadLocalUtil.getCurrentId());
                shoppingCart.setCreateTime(LocalDateTime.now());
                return shoppingCart;
            }).collect(Collectors.toList());
            shoppingCartMapper.batchSave(shoppingCartList);
        }
    }

    @Override
    public PageResult conditionSearch(OrdersPageQueryDTO dto) {
        int page = dto.getPage();
        int pageSize = dto.getPageSize();
        if(page==0){
            page=1;
        }
        if(pageSize==0){
            pageSize=10;
        }
        PageHelper.startPage(page,pageSize);
        List<Orders> ordersList = orderMapper.findList(dto);
        PageInfo<Orders> pageInfo = PageInfo.of(ordersList);
        List<OrderVO> voList = new ArrayList<>();
        if(CollectionUtil.isNotEmpty(ordersList)){
            StringBuilder builder=new StringBuilder();
            for (Orders orders : ordersList) {
                List<OrderDetail> orderDetails = orderDetailMapper.findByOrderId(orders.getId());
                for (OrderDetail orderDetail : orderDetails) {
                    builder.append(orderDetail.getName()+"*"+orderDetail.getNumber()+";");
                }
                OrderVO vo = BeanUtil.copyProperties(orders, OrderVO.class);
                vo.setOrderDishes(builder.toString());
                voList.add(vo);
            }

        }

        return new PageResult(pageInfo.getTotal(),voList);

    }

    @Override
    public OrderStatisticsVO statistics() {
        OrderStatisticsVO vo =new OrderStatisticsVO();
       vo.setConfirmed(orderMapper.orderByStatus(Orders.CONFIRMED));
       vo.setDeliveryInProgress(orderMapper.orderByStatus(Orders.DELIVERY_IN_PROGRESS));
       vo.setToBeConfirmed(orderMapper.orderByStatus(Orders.TO_BE_CONFIRMED));
        return vo;
    }

    @Override
    public OrderVO details(Long id) {
        Orders order = orderMapper.findById(id);
        List<OrderDetail> detailList = orderDetailMapper.findByOrderId(id);
        OrderVO vo = BeanUtil.copyProperties(order, OrderVO.class);
        vo.setOrderDetailList(detailList);
        return vo;
    }

    @Override
    public void confirm(OrdersConfirmDTO dto) {

        Orders order = orderMapper.findById(dto.getId());
        if(order.getStatus()!=Orders.TO_BE_CONFIRMED){
            throw new BusinessException("订单未处于待接单状态");
        }
        order.setStatus(Orders.CONFIRMED);
        orderMapper.update(order);
    }

    @Override
    public void rejection(OrdersRejectionDTO dto) {
        Orders order = orderMapper.findById(dto.getId());
        if(order.getStatus()!=Orders.TO_BE_CONFIRMED){
            throw new BusinessException("订单未处于待接单状态");
        }
        order.setCancelReason(dto.getRejectionReason());
        order.setCancelTime(LocalDateTime.now());
        order.setStatus(Orders.CANCELLED);
        if(order.getPayStatus().equals(Orders.PAID)){
            //此处应退款(无法进行)
            order.setPayStatus(Orders.REFUND);
        }
        orderMapper.update(order);
    }

    @Override
    public void cancelOrder(OrdersCancelDTO dto) {
        Orders order = orderMapper.findById(dto.getId());
        order.setCancelReason(dto.getCancelReason());
        order.setCancelTime(LocalDateTime.now());
        order.setStatus(Orders.CANCELLED);
        if(order.getPayStatus().equals(Orders.PAID)){
            //此处应退款(无法进行)
            order.setPayStatus(Orders.REFUND);
        }
        orderMapper.update(order);
    }

    @Override
    public void delivery(Long id) {
        Orders order = orderMapper.findById(id);
        if(order.getStatus()!=Orders.CONFIRMED){
            throw new BusinessException("订单未处于待派送状态");
        }
        order.setStatus(Orders.DELIVERY_IN_PROGRESS);
        orderMapper.update(order);
    }

    @Override
    public void complete(Long id) {
        Orders order = orderMapper.findById(id);
        if(order.getStatus()!=Orders.DELIVERY_IN_PROGRESS){
            throw new BusinessException("订单未处于派送状态");
        }
        order.setStatus(Orders.COMPLETED);
        orderMapper.update(order);
    }

    @Override
    public void reminder(Long id) {
        Orders order = orderMapper.findById(id);
        if(order==null){
            throw new BusinessException("订单不存在");
        }
        Map map = new HashMap();
        map.put("type", 2);
        map.put("orderId", id);
        map.put("content", "订单号：" + order.getNumber());
        webSocketServer.sendToAllClient(JSON.toJSONString(map));
    }


}
